package com.study.thirdpartyeventconsumer.controller.google.complate;

import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPMessage;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import javax.mail.search.AndTerm;
import javax.mail.search.ComparisonTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.SentDateTerm;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 邮件拉取工具类
 */
public class EmailFetchUtil {
    private String host;
    private String username;
    private String password;
    private String attachmentSavePath;

    public EmailFetchUtil(String host, String username, String password, String attachmentSavePath) {
        this.host = host;
        this.username = username;
        this.password = password;
        this.attachmentSavePath = attachmentSavePath;
    }

    /**
     * 获取最后一封邮件
     */
    public ArrayList<EmailMessage> fetchEmail(Date startDate, Date endDate) throws MessagingException, IOException {
        Properties props = new Properties();
        props.setProperty("mail.store.protocol", "imap");
        props.setProperty("mail.imap.host", host);
        props.setProperty("mail.imap.port", "993");
        props.setProperty("mail.imap.ssl.enable", "true");
        props.setProperty("mail.imap.partialfetch", "false");
        props.setProperty("mail.imaps.partialfetch", "false");
        Session session = Session.getInstance(props);
        Store store = null;
        Folder folder = null;

        try {
            store = session.getStore("imap");
            store.connect(username, password);

            folder = store.getFolder("INBOX");
            IMAPFolder imapFolder = (IMAPFolder) folder;
            imapFolder.doCommand(p -> {
                p.id("a");
                return null;
            });
            folder.open(Folder.READ_ONLY);
            SearchTerm dateRangeTerm = new AndTerm(
                    new SentDateTerm(ComparisonTerm.GE, startDate),
                    new SentDateTerm(ComparisonTerm.LE, endDate)
            );
            Message[] search = folder.search(dateRangeTerm);
            ArrayList<EmailMessage> messageList = new ArrayList<>();
            for (Message message : search) {
                messageList.add(convertToEmailMessage(message));
            }
            return messageList;
        } finally {
            if (folder != null && folder.isOpen()) {
                folder.close(false);
            }
            if (store != null) {
                store.close();
            }
        }
    }

    /**
     * 将JavaMail消息转换为自定义EmailMessage对象
     */
    private EmailMessage convertToEmailMessage(Message message) throws MessagingException, IOException {
        EmailMessage emailMessage = new EmailMessage();

        // 设置基本信息
        emailMessage.setMessageId(getMessageId(message));
        emailMessage.setReceivedDate(message.getSentDate());
        emailMessage.setSubject(message.getSubject());
        emailMessage.setFromAddress(InternetAddress.toString(message.getFrom()));
        emailMessage.setToAddress(InternetAddress.toString(message.getRecipients(Message.RecipientType.TO)));

        // 处理内容和附件
        List<EmailAttachment> attachments = new ArrayList<>();
        StringBuilder htmlContent = new StringBuilder();

        processMessagePart(message, htmlContent, attachments);

        emailMessage.setHtmlContent(htmlContent.toString());
        emailMessage.setAttachments(attachments);

        return emailMessage;
    }

    /**
     * 处理邮件部分（内容和附件）
     */
    private void processMessagePart(Part part, StringBuilder htmlContent, List<EmailAttachment> attachments)
            throws MessagingException, IOException {
        if (part.isMimeType("text/html")) {
            htmlContent.append((String) part.getContent());
        } else if (part.isMimeType("multipart/*")) {
            Multipart multipart = (Multipart) part.getContent();
            for (int i = 0; i < multipart.getCount(); i++) {
                processMessagePart(multipart.getBodyPart(i), htmlContent, attachments);
            }
        } else if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) ||
                Part.INLINE.equalsIgnoreCase(part.getDisposition())) {
            // 处理附件
            EmailAttachment attachment = saveAttachment(part);
            if (attachment != null) {
                attachments.add(attachment);
            }
        }
    }

    /**
     * 保存附件并返回附件对象
     */
    private EmailAttachment saveAttachment(Part part) throws MessagingException, IOException {
        String fileName = MimeUtility.decodeText(part.getFileName());
        if (fileName == null) {
            return null;
        }

        EmailAttachment attachment = new EmailAttachment();
        attachment.setContentType(part.getContentType());

        // 获取Content-ID
        String[] contentIds = part.getHeader("Content-ID");
        if (contentIds != null && contentIds.length > 0) {
            attachment.setContentId(contentIds[0].replaceAll("[<>]", ""));
        }

        // 保存附件
        String filePath = /*attachmentSavePath + File.separator +*/ fileName;
        try (InputStream is = part.getInputStream();
             FileOutputStream fos = new FileOutputStream(filePath)) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            long size = 0;
            while ((bytesRead = is.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
                size += bytesRead;
            }
            attachment.setIsAttachment(Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()));
            attachment.setFileUrl(filePath);
            attachment.setFileSize(size);
        }

        return attachment;
    }

    /**
     * 获取邮件的Message-ID
     */
    private String getMessageId(Message message) throws MessagingException {
        String[] headers = message.getHeader("Message-ID");
        if (headers != null && headers.length > 0) {
            return headers[0];
        }
        // 如果没有Message-ID，使用IMAP UID
        if (message instanceof IMAPMessage) {
            return "IMAP-" + ((IMAPMessage) message).getContentID();
        }
        // 最后的备选方案
        return "NO-ID-" + message.getSentDate().getTime();
    }
}
